package service

import (
	"encoding/json"
	model "kingbloc.dts/models"
	"kingbloc.dts/tools"
	user "kingbloc.sso/user"
	"kingbloc.util/util"
	"net/url"
	"strconv"
	"strings"
	"sync"
)

var LayerNo int64

// 报单对外服务
func PlaceAnOrder(mob, introducerMob string, parentOrderId int64, price float64, isManual bool, lockPlaceAnOrder *sync.Mutex) map[string]string {
	lockPlaceAnOrder.Lock()
	defer lockPlaceAnOrder.Unlock()
	result := make(map[string]string, 0)
	result["status"] = "ok"
	result["msg"] = "报单成功！"
	newOrder := new(model.Orderr)
	// TODO： 数据规范校验
	// 推荐人手机号不能是自己
	if mob == introducerMob {
		result["status"] = "0"
		result["msg"] = "报单失败，推荐人不能是自己！"
		return result
	}
	if isManual {
		newOrder = manualPlaceAnOrder(mob, introducerMob, parentOrderId, price)
	} else {
		newOrder = systemPlaceAnOrder(mob, introducerMob, parentOrderId, price)
	}

	if newOrder == nil {
		result["status"] = "1"
		result["msg"] = "报单失败，重新指定上级！"
	}

	return result

}

// 系统报单代理，仅用于测试和默认数据调用
func ProxySystemPlaceAnOrder(mob, introducerMob string, parentOrderId int64, price float64) {
	systemPlaceAnOrder(mob, introducerMob, parentOrderId, price)
}

// 系统报单: 自动指定一区位置
func systemPlaceAnOrder(mob, introducerMob string, parentOrderId int64, price float64) (order *model.Orderr) {
	FindLastLayerFirstOrderId(parentOrderId)
	return createOrder(mob, introducerMob, LayerNo, price)
}

// 手动报单: 会员指定单子上层节点位置
func manualPlaceAnOrder(mob, introducerMob string, parentOrderId int64, price float64) (order *model.Orderr) {
	//TODO： 禁止外部人员添加顶层账户
	if parentOrderId == 0 {
		return nil
	}
	orders := new(model.Orderr).NextFloorOrdersByOrderId(parentOrderId)
	// 指定位置下面是否已满制度倍增个数的节点
	if len(orders) == tool.GlobalMultiply_2 {
		return nil
	}
	order = createOrder(mob, introducerMob, parentOrderId, price)
	return
}

// 报单
func createOrder(mob, introducerMob string, parentOrderId int64, price float64) (order *model.Orderr) {
	userInfo := tool.UserInfoByMob(mob)
	parentOrder := new(model.Orderr)
	parentOrder.ById(parentOrderId)
	//
	introducer := tool.UserInfoByMob(introducerMob)

	// TODO: 暂时放开
	if introducer == nil {
		//return nil
		introducer = new(user.User)
	}
	if userInfo != nil { // 存在 mob 账户
		order = seconedCreateOrder(userInfo, parentOrder, price, introducer.Id)
	} else { // 不存在 mob 账户
		order = firstCreateOrder(mob, parentOrder, price, introducer.Id)
	}

	return
}

// 系统报单时：自动寻找最底层的第一个单
// 寻找自动报单的上层id ( parent id )
func FindLastLayerFirstOrderId(orderid int64) {

	order := new(model.Orderr)
	var count = order.Count()

	if count == 0 {
		LayerNo = 0
		return
	}

	LayerNo = orderid // 次指定的上层id没有下层就以此为上层id
	order.NextFloorFirstOrderById(orderid)
	if order.Id > 0 {
		if order.Id == order.ParentId {
			return
		}
		LayerNo = order.Id
		FindLastLayerFirstOrderId(order.Id)
	}

}

// 第二次报单
func seconedCreateOrder(userInfo *user.User, parentOrder *model.Orderr, price float64, introducerId int64) *model.Orderr {

	var account *model.Account
	acc := model.FindAccountBySsoId(userInfo.Id)
	if acc != nil { // 已经存在 account 账户
		account = acc
	} else { // 还没有 account 账户
		// 获取 acount 账户
		account = model.NewAccount()
		account.Password2 = util.Md5EncodeForPassword(userInfo.Mobile)
		account.SsoUserId = userInfo.Id
		account.Add()
	}

	// 创建一个订单
	order := model.NewOrder()
	order.IntroducerId = introducerId
	order.AccountId = account.Id
	order.ParentId = parentOrder.Id
	order.Layer = parentOrder.Layer + 1
	order.Price = price
	order.Sort = order.LayerByRowCount(order.Layer) + 1
	order.Add()

	// 更新account 信息
	newOrderIdStr := strconv.FormatInt(order.Id, 10)
	if !strings.Contains(account.MyOrderIds, newOrderIdStr) {
		account.MyOrderIds += newOrderIdStr + ","
	}
	//
	account.Update()

	// 记录当天业绩
	model.NewToday(order.Id, account.Id).Add()

	return order

}

// 第一次报单
func firstCreateOrder(mob string, parentOrder *model.Orderr, price float64, introducerId int64) *model.Orderr {
	//fmt.Printf("--first create order is mob : %v --\n", mob)
	// 注册一个sso账户
	user := RegisterSsoUser(mob, mob)

	// 注册一个acount账户
	account := model.NewAccount()
	account.SsoUserId = user.Id
	account.Password2 = util.Md5EncodeForPassword(mob)
	account.Add()

	// 创建一个订单
	order := model.NewOrder()
	order.IntroducerId = introducerId
	order.AccountId = account.Id
	order.ParentId = parentOrder.Id
	order.Layer = parentOrder.Layer + 1
	order.Price = price
	order.Sort = order.LayerByRowCount(order.Layer) + 1
	order.Add()

	// 更新account 信息
	newOrderIdStr := strconv.FormatInt(order.Id, 10)
	if !strings.Contains(account.MyOrderIds, newOrderIdStr) {
		account.MyOrderIds += newOrderIdStr + ","
	}
	//
	account.Update()

	// 记录当天业绩
	model.NewToday(order.Id, account.Id).Add()

	return order
}

func RegisterSsoUser(uname, pwd string) *user.User {

	param := url.Values{}
	param.Set("uname", uname)
	param.Set("pwd", pwd)

	conf := tool.GetConfig()
	ssoUrl := conf.Get("sso", "url")
	ssoUrl += "/reg"
	dataArr, _ := util.Post(ssoUrl, param)
	user := new(user.User)
	if len(dataArr) > 0 {
		json.Unmarshal(dataArr, &user)
	}
	if user == nil {
		return nil
	}
	if user.Id == 0 {
		return nil
	}

	return user

}

func FindOrdersByAccountId(id int64) []*model.Orderr {
	return new(model.Orderr).ByAccountId(id)
}

func FindOrdersByParentLayerOrderId(id int64) []*model.Orderr {
	return new(model.Orderr).NextFloorOrdersByOrderId(id)

}

func MyRecommended(id int64) []*model.Orderr {

	return new(model.Orderr).ByIntroducerId(id)
}

func InitTablesDefaultData() {
	rebuildTables()
	ProxySystemPlaceAnOrder("15100000000", "0", 0, 30000)
	account := FindAccountByMob("15100000000")
	account.Types = 3
	account.UpdateCols("types")
	//
	CreateOrders()
	award := new(Award)
	award.CalcAllAward()
	award.CalcAwardLayer()
	award.CalcAwardAmount()
	award.CalcAwardLucky()
	award.CalcAwardManagement()
	award.CalcAwardCharm(account)

}

func rebuildTables() {
	model.MysqlEngine.DropTables(new(model.Orderr), new(model.Account), new(model.Today), new(model.Approve))
	model.MysqlEngine.CreateTables(new(model.Orderr), new(model.Account), new(model.Today), new(model.Approve))
	model.MysqlEngine.Sync2(new(model.Orderr), new(model.Account), new(model.Today), new(model.Approve))
	//
	model.MysqlEngine.DropTables(new(model.LayerAward), new(model.AmountAward), new(model.LuckyAward), new(model.ManagementAward), new(model.CharmAward))
	model.MysqlEngine.CreateTables(new(model.LayerAward), new(model.AmountAward), new(model.LuckyAward), new(model.ManagementAward), new(model.CharmAward))
	model.MysqlEngine.Sync2(new(model.LayerAward), new(model.AmountAward), new(model.LuckyAward), new(model.ManagementAward), new(model.CharmAward))

}

var lockPlaceAnOrder sync.Mutex = sync.Mutex{}

func CreateOrders() {

	PlaceAnOrder("15100000015", "15100000000", 1, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000016", "15100000015", 1, 10000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000017", "15100000015", 2, 20000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000018", "15100000017", 2, 30000, true, &lockPlaceAnOrder) //5
	PlaceAnOrder("15100000019", "15100000017", 4, 20000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000020", "15100000018", 6, 20000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000021", "15100000016", 5, 20000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000022", "15100000016", 3, 10000, true, &lockPlaceAnOrder)

	// 10
	PlaceAnOrder("15100000023", "15100000016", 8, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000024", "15100000019", 3, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000025", "15100000020", 5, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000026", "15100000020", 9, 10000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000027", "15100000021", 4, 20000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000028", "15100000022", 14, 30000, true, &lockPlaceAnOrder) //5
	PlaceAnOrder("15100000000", "15100000024", 7, 20000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000030", "15100000015", 10, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000031", "15100000015", 11, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000032", "15100000019", 13, 3000, true, &lockPlaceAnOrder)
	// 20
	PlaceAnOrder("15100000033", "15100000025", 19, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000034", "15100000000", 16, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000035", "15100000026", 21, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000036", "15100000027", 17, 10000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000037", "15100000028", 23, 20000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000037", "15100000028", 22, 30000, true, &lockPlaceAnOrder) //5
	PlaceAnOrder("15100000038", "15100000028", 25, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000039", "15100000030", 13, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000040", "15100000031", 12, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000041", "15100000000", 24, 3000, true, &lockPlaceAnOrder)
	// 30
	PlaceAnOrder("15100000042", "15100000032", 29, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000043", "15100000033", 20, 30000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000044", "15100000034", 28, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000045", "15100000035", 32, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000046", "15100000036", 32, 10000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000047", "15100000037", 33, 3000, true, &lockPlaceAnOrder) //5
	PlaceAnOrder("15100000048", "15100000038", 35, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000049", "15100000039", 15, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000050", "15100000040", 15, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000051", "15100000041", 18, 3000, true, &lockPlaceAnOrder)
	// 40
	PlaceAnOrder("15100000052", "15100000043", 6, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000053", "15100000044", 16, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000054", "15100000045", 38, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000055", "15100000000", 28, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000056", "15100000046", 12, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000057", "15100000047", 40, 3000, true, &lockPlaceAnOrder) //5
	PlaceAnOrder("15100000058", "15100000048", 41, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000059", "15100000049", 45, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000060", "15100000050", 31, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000061", "15100000051", 27, 3000, true, &lockPlaceAnOrder)
	// 50
	PlaceAnOrder("15100000062", "15100000052", 11, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000063", "15100000053", 8, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000064", "15100000054", 46, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000065", "15100000055", 26, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000066", "15100000056", 24, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000067", "15100000057", 29, 3000, true, &lockPlaceAnOrder) //5
	PlaceAnOrder("15100000068", "15100000058", 36, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000069", "15100000059", 31, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000070", "15100000060", 49, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000071", "15100000061", 39, 3000, true, &lockPlaceAnOrder)
	// 60
	PlaceAnOrder("15100000000", "15100000061", 56, 30000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000072", "15100000061", 57, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000073", "15100000061", 61, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000074", "15100000061", 55, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000075", "15100000061", 53, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000076", "15100000061", 59, 3000, true, &lockPlaceAnOrder) //5
	PlaceAnOrder("15100000077", "15100000061", 58, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000078", "15100000061", 62, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000079", "15100000061", 48, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000072", "15100000061", 57, 3000, true, &lockPlaceAnOrder)
	// 70
	PlaceAnOrder("15100000080", "15100000061", 47, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000081", "15100000061", 46, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000082", "15100000061", 22, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000083", "15100000061", 37, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000084", "15100000061", 17, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000085", "15100000000", 68, 3000, true, &lockPlaceAnOrder) // 5
	PlaceAnOrder("15100000086", "15100000000", 58, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000087", "15100000000", 50, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000088", "15100000000", 52, 3000, true, &lockPlaceAnOrder)
	PlaceAnOrder("15100000089", "15100000061", 47, 3000, true, &lockPlaceAnOrder)
	// 80
	PlaceAnOrder("15100000090", "15100000061", 78, 3000, true, &lockPlaceAnOrder)
}
